package service

import (
	"fmt"
	"gitee.com/kudingc/role_proxy/common"
	"gitee.com/kudingc/role_proxy/models"
	"gitee.com/kudingc/role_proxy/service/util"
	"github.com/casbin/casbin"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"strings"
)

// Authorize 拦截器
func Authorize(e *casbin.Enforcer) gin.HandlerFunc {
	return func(c *gin.Context) {
		var roleCheckSuccess bool
		var jwt *util.Claims
		var userRole models.SysUserRole

		// 解析jwt
		if jwt, _ = util.CheckAuthorization(c); jwt == nil {
			c.JSON(http.StatusOK, gin.H{"state": -1, "msg": "Token 验证失败"})
			c.Abort()
			return
		}

		// 根据用户id获取用户角色列表
		userRole.UserId = jwt.Credentials.UserId
		roleIds, err := userRole.GetRoleIdsForUserId()
		if err != nil {
			c.JSON(http.StatusOK, gin.H{"state": -1, "msg": "用户信息验证失败"})
			c.Abort()
			return
		}

		// 将userId,roleIds添加到header中
		c.Request.Header.Add("User-Id", strconv.Itoa(jwt.Credentials.UserId))
		c.Request.Header.Add("Role-Ids", roleIds)

		//获取请求的URI
		obj := c.Request.URL.RequestURI()
		//获取请求方法
		act := c.Request.Method

		// 遍历角色，判断策略是否满足
		roleIdList := strings.Split(roleIds, ",")
		roleCheckSuccess = false
		for _, sub := range roleIdList {
			//判断策略中是否存在
			if ok := e.Enforce(sub, obj, act); ok {
				roleCheckSuccess = true
				break
			}
		}
		if roleCheckSuccess {
			common.ZhLogger.Info(fmt.Sprintf("用户id%d,用户名%s权限验证%s通过", jwt.Credentials.UserId, jwt.Credentials.UserName, obj))
			c.Next()
		} else {
			common.ZhLogger.Info(fmt.Sprintf("用户id%d,用户名%s权限验证%s未通过", jwt.Credentials.UserId, jwt.Credentials.UserName, obj))
			c.JSON(http.StatusOK, gin.H{
				"msg": "很遗憾,权限验证没有通过",
			})
			c.Abort()
		}
	}
}
